/* command */
const { getDiffCommand } = require('../model/command')
/* model */
const tree = require('../model/madgeTree')
const modulesEntryMap = require('../model/moduleEntry')
/* process */
const CP = require('child_process')
/* util */
const PathUtil = require('path')

const exec = CP.exec
const path = PathUtil.posix

const PROJECT_ENTRY = 'src/common/entry.js'
const treeData = tree
let originDiffFileArray = []

function getDiffFileArray(branchOrCommit) {
  
  const GITDIFF = getDiffCommand(branchOrCommit)
  
  // 执行 git 的命令
  return (
    new Promise((resolve, reject) => {
      exec(GITDIFF, (error, stdout) => {
        if (error) {
          console.error(`exec error: ${error}`)
          reject(error)
        }
        
        // 对返回结果进行处理，拿到要检查的文件列表
        const diffFileArray = (
          stdout.split('\n')
            .filter(file => file)
            .map(file => path.normalize(file))
        )
        
        resolve(diffFileArray)
      })
    })
  )
  
}

// 计算增量入口
let incrementEntries = []
function getIncrementEntries(diffFiles) {
  diffFiles = [...new Set(diffFiles)]
  
  if (diffFiles.includes(PROJECT_ENTRY)) {
    return [PROJECT_ENTRY]
  }
  
  if (isRoot(diffFiles)) {
    return diffFiles
  }
  
  for (const treeKey in treeData) {
    treeData[treeKey].forEach((item) => {
      if (intersection(treeData[treeKey], diffFiles)) {
        incrementEntries.push(treeKey)
      }
    })
  }
  
  diffFiles = incrementEntries.map((item) => item)
  incrementEntries = []
  
  return getIncrementEntries(diffFiles)
}

// 是否为根
function isRoot(files) {
  return files.every((file) => modulesEntryMap[file])
}

// 判断两个数组是否存在交集
function intersection(arr1, arr2) {
  let flag = false
  
  arr1.forEach((ele) => {
    if (arr2.includes(ele)) {
      flag = true
    }
  })
  
  return flag
}

async function getEntryMap(branchOrCommit) {
  try {
    let diffFilesArray = await getDiffFileArray(branchOrCommit)
    let entries = []
    let incrementEntriesInside = []
    let isAll = false
    
    originDiffFileArray = diffFilesArray.slice()
    
    for (let index in originDiffFileArray) {
      incrementEntriesInside = getIncrementEntries([originDiffFileArray[index]])
      
      if (incrementEntriesInside.includes(PROJECT_ENTRY)) {
        isAll = true
        break
      } else {
        entries.concat(incrementEntriesInside)
      }
      
    }
    
    if (isAll) {
      return modulesEntryMap
    }
    
    let entryMap = {}
    entries = [...new Set(entries)]
    entries.forEach(entryKey => {
      entryMap[entryKey] = modulesEntryMap[entryKey]
    })
    
    return entryMap
    
  } catch (error) {
    return modulesEntryMap
  }
}

exports.getEntryMap = getEntryMap

module.exports = {
  getEntryMap
}
